/* task_queue.c
 * 任务队列相关内容的具体实现 
 * */

#include "../include/head.h"
#include "../include/task_queue.h"

//初始化任务队列
int taskQueInit(pTaskQue_t pQue){
    pQue->exitFlag = 0;
    pQue->exited = 0;
    pQue->size = 0;
    pQue->pHead = NULL;
    pQue->pTail = NULL;
    pthread_cond_init(&pQue->cond1, NULL);
    pthread_cond_init(&pQue->cond2, NULL);
    pthread_mutex_init(&pQue->mutex, NULL);
    return 0;
}

//把新的任务结点插入任务队列的队尾
int taskQueInsert(pTaskQue_t pQue, pTaskNode_t pNew){
    //函数只实现功能，加锁解锁应该在调用它的地方上锁，避免造成自死锁
    /* pthread_mutex_lock(&pQue->mutex);   //访问任务队列前要加锁 */
    if(pQue->pHead == NULL){
        //如果任务队列为空，直接插入
        pQue->pHead = pNew;
        pQue->pTail = pNew;
    }
    else{
        //如果队列不为空，采用尾插法，把新结点插入队尾
        pQue->pTail->pNext = pNew;
        pQue->pTail = pNew;
    }
    ++pQue->size;
    /* pthread_mutex_unlock(&pQue->mutex); //解锁 */
    return 0;
}

//获取任务队列的队首结点
int taskQueGet(pTaskQue_t pQue, pTaskNode_t *pGet){
    /* pthread_mutex_lock(&pQue->mutex); */
    if(1 == pQue->size){
        //如果队列中只有一个结点，获取结点，并把队列置为空
        *pGet = pQue->pHead;
        pQue->pHead = NULL;
        pQue->pTail = NULL;
        pQue->size--;
    }
    else{
        //如果队列中有两个及以上的元素，直接取出队首结点
        *pGet = pQue->pHead;
        pQue->pHead = pQue->pHead->pNext;
        --pQue->size;
    }
    /* pthread_mutex_unlock(&pQue->mutex);//解锁 */
    return 0;
}
